home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / daemons / nfs / nfs-serv.2be / nfs-serv / nfs-server-2.2beta16 / mountlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-08  |  11.3 KB  |  477 lines

  1. /* mountlist.c -- return a list of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include "mountlist.h"
  25.  
  26. #ifdef STDC_HEADERS
  27. #include <stdlib.h>
  28. #else
  29. void free ();
  30. #endif
  31. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  32. #include <string.h>
  33. #else
  34. #include <strings.h>
  35. #endif
  36.  
  37. char *strstr ();
  38. char *xmalloc ();
  39. char *xrealloc ();
  40. char *xstrdup ();
  41. void error ();
  42.  
  43. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  44. #  include <sys/mount.h>
  45. #  include <sys/fs_types.h>
  46. #endif /* MOUNTED_GETFSSTAT */
  47.  
  48. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  49. #include <mntent.h>
  50. #if !defined(MOUNTED)
  51. #  if defined(MNT_MNTTAB)    /* HP-UX.  */
  52. #    define MOUNTED MNT_MNTTAB
  53. #  endif
  54. #  if defined(MNTTABNAME)    /* Dynix.  */
  55. #    define MOUNTED MNTTABNAME
  56. #  endif
  57. #endif
  58. #endif
  59.  
  60. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  61. #include <sys/mount.h>
  62. #endif
  63.  
  64. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  65. #include <sys/param.h>
  66. #include <sys/mount.h>
  67. #include <sys/fs_types.h>
  68. #endif
  69.  
  70. #ifdef MOUNTED_FREAD        /* SVR2.  */
  71. #include <mnttab.h>
  72. #endif
  73.  
  74. #ifdef MOUNTED_FREAD_FSTYP    /* SVR3.  */
  75. #include <mnttab.h>
  76. #include <sys/fstyp.h>
  77. #include <sys/statfs.h>
  78. #endif
  79.  
  80. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  81. #include <sys/mnttab.h>
  82. #endif
  83.  
  84. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  85. #include <fshelp.h>
  86. #include <sys/vfs.h>
  87. #endif
  88.  
  89. #ifdef DOLPHIN
  90. /* So special that it's not worth putting this in autoconf.  */
  91. #undef MOUNTED_FREAD_FSTYP
  92. #define MOUNTED_GETMNTTBL
  93. #endif
  94.  
  95. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  96. /* Return the value of the hexadecimal number represented by CP.
  97.    No prefix (like '0x') or suffix (like 'h') is expected to be
  98.    part of CP. */
  99.  
  100. static int
  101. xatoi (cp)
  102.      char *cp;
  103. {
  104.   int val;
  105.   
  106.   val = 0;
  107.   while (*cp)
  108.     {
  109.       if (*cp >= 'a' && *cp <= 'f')
  110.     val = val * 16 + *cp - 'a' + 10;
  111.       else if (*cp >= 'A' && *cp <= 'F')
  112.     val = val * 16 + *cp - 'A' + 10;
  113.       else if (*cp >= '0' && *cp <= '9')
  114.     val = val * 16 + *cp - '0';
  115.       else
  116.     break;
  117.       cp++;
  118.     }
  119.   return val;
  120. }
  121. #endif /* MOUNTED_GETMNTENT1.  */
  122.  
  123. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  124. static char *
  125. fstype_to_string (t)
  126.      short t;
  127. {
  128.   switch (t)
  129.     {
  130.     case MOUNT_UFS:
  131.       return "ufs";
  132.     case MOUNT_NFS:
  133.       return "nfs";
  134. #ifdef MOUNT_PC
  135.     case MOUNT_PC:
  136.       return "pc";
  137. #endif
  138. #ifdef MOUNT_MFS
  139.     case MOUNT_MFS:
  140.       return "mfs";
  141. #endif
  142. #ifdef MOUNT_LO
  143.     case MOUNT_LO:
  144.       return "lo";
  145. #endif
  146. #ifdef MOUNT_TFS
  147.     case MOUNT_TFS:
  148.       return "tfs";
  149. #endif
  150. #ifdef MOUNT_TMP
  151.     case MOUNT_TMP:
  152.       return "tmp";
  153. #endif
  154.     default:
  155.       return "?";
  156.     }
  157. }
  158. #endif /* MOUNTED_GETMNTINFO */
  159.  
  160. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  161. static char *
  162. fstype_to_string (t)
  163.      int t;
  164. {
  165.   struct vfs_ent *e;
  166.  
  167.   e = getvfsbytype (t);
  168.   if (!e || !e->vfsent_name)
  169.     return "none";
  170.   else
  171.     return e->vfsent_name;
  172. }
  173. #endif /* MOUNTED_VMOUNT */
  174.  
  175. /* Return a list of the currently mounted filesystems, or NULL on error.
  176.    Add each entry to the tail of the list so that they stay in order.
  177.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  178.    the returned list are valid.  Otherwise, they might not be.
  179.    If ALL_FS is zero, do not return entries for filesystems that
  180.    are automounter (dummy) entries.  */
  181.  
  182. struct mount_entry *
  183. read_filesystem_list (need_fs_type, all_fs)
  184.      int need_fs_type, all_fs;
  185. {
  186.   struct mount_entry *mount_list;
  187.   struct mount_entry *me;
  188.   struct mount_entry *mtail;
  189.  
  190.   /* Start the list off with a dummy entry. */
  191.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  192.   me->me_next = NULL;
  193.   mount_list = mtail = me;
  194.  
  195. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  196.   {
  197.     struct mntent *mnt;
  198.     char *table = MOUNTED;
  199.     FILE *fp;
  200.     char *devopt;
  201.  
  202.     fp = setmntent (table, "r");
  203.     if (fp == NULL)
  204.       return NULL;
  205.  
  206.     while ((mnt = getmntent (fp)))
  207.       {
  208.     if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  209.             || !strcmp (mnt->mnt_type, "auto")))
  210.       continue;
  211.  
  212.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  213.     me->me_devname = xstrdup (mnt->mnt_fsname);
  214.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  215.     me->me_type = xstrdup (mnt->mnt_type);
  216.     devopt = strstr (mnt->mnt_opts, "dev=");
  217.     if (devopt)
  218.       {
  219.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  220.           me->me_dev = xatoi (devopt + 6);
  221.         else
  222.           me->me_dev = xatoi (devopt + 4);
  223.       }
  224.     else
  225.       me->me_dev = -1;    /* Magic; means not known yet. */
  226.     me->me_next = NULL;
  227.  
  228.     /* Add to the linked list. */
  229.     mtail->me_next = me;
  230.     mtail = me;
  231.       }
  232.  
  233.     if (endmntent (fp) == 0)
  234.       return NULL;
  235.   }
  236. #endif /* MOUNTED_GETMNTENT1. */
  237.  
  238. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  239.   {
  240.     struct statfs *fsp;
  241.     int entries;
  242.  
  243.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  244.     if (entries < 0)
  245.       return NULL;
  246.     while (entries-- > 0)
  247.       {
  248.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  249.     me->me_devname = xstrdup (fsp->f_mntfromname);
  250.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  251.     me->me_type = fstype_to_string (fsp->f_type);
  252.     me->me_dev = -1;    /* Magic; means not known yet. */
  253.     me->me_next = NULL;
  254.  
  255.     /* Add to the linked list. */
  256.     mtail->me_next = me;
  257.     mtail = me;
  258.     fsp++;
  259.       }
  260.   }
  261. #endif /* MOUNTED_GETMNTINFO */
  262.  
  263. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  264.   {
  265.     int offset = 0;
  266.     int val;
  267.     struct fs_data fsd;
  268.  
  269.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  270.               (char *) 0)) > 0)
  271.       {
  272.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  273.     me->me_devname = xstrdup (fsd.fd_req.devname);
  274.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  275.     me->me_type = gt_names[fsd.fd_req.fstype];
  276.     me->me_dev = fsd.fd_req.dev;
  277.     me->me_next = NULL;
  278.  
  279.     /* Add to the linked list. */
  280.     mtail->me_next = me;
  281.     mtail = me;
  282.       }
  283.     if (val < 0)
  284.       return NULL;
  285.   }
  286. #endif /* MOUNTED_GETMNT. */
  287.  
  288. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  289.   {
  290.     int numsys, counter, bufsize;
  291.     struct statfs *stats;
  292.  
  293.     numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
  294.     if (numsys < 0)
  295.       return (NULL);
  296.  
  297.     bufsize = (1 + numsys) * sizeof (struct statfs);
  298.     stats = (struct statfs *)xmalloc (bufsize);
  299.     numsys = getfsstat (stats, bufsize, MNT_WAIT);
  300.  
  301.     if (numsys < 0)
  302.       {
  303.     free (stats);
  304.     return (NULL);
  305.       }
  306.  
  307.     for (counter = 0; counter < numsys; counter++)
  308.       {
  309.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  310.     me->me_devname = xstrdup (stats[counter].f_mntfromname);
  311.     me->me_mountdir = xstrdup (stats[counter].f_mntonname);
  312.     me->me_type = mnt_names[stats[counter].f_type];
  313.     me->me_dev = -1;    /* Magic; means not known yet. */
  314.     me->me_next = NULL;
  315.  
  316.     /* Add to the linked list. */
  317.     mtail->me_next = me;
  318.     mtail = me;
  319.       }
  320.  
  321.     free (stats);
  322.   }
  323. #endif /* MOUNTED_GETFSSTAT */
  324.  
  325. #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23].  */
  326.   {
  327.     struct mnttab mnt;
  328.     char *table = "/etc/mnttab";
  329.     FILE *fp;
  330.  
  331.     fp = fopen (table, "r");
  332.     if (fp == NULL)
  333.       return NULL;
  334.  
  335.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  336.       {
  337.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  338. #ifdef GETFSTYP            /* SVR3.  */
  339.     me->me_devname = xstrdup (mnt.mt_dev);
  340. #else
  341.     me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
  342.     strcpy (me->me_devname, "/dev/");
  343.     strcpy (me->me_devname + 5, mnt.mt_dev);
  344. #endif
  345.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  346.     me->me_dev = -1;    /* Magic; means not known yet. */
  347.     me->me_type = "";
  348. #ifdef GETFSTYP            /* SVR3.  */
  349.     if (need_fs_type)
  350.       {
  351.         struct statfs fsd;
  352.         char typebuf[FSTYPSZ];
  353.  
  354.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  355.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  356.           me->me_type = xstrdup (typebuf);
  357.       }
  358. #endif
  359.     me->me_next = NULL;
  360.  
  361.     /* Add to the linked list. */
  362.     mtail->me_next = me;
  363.     mtail = me;
  364.       }
  365.  
  366.     if (fclose (fp) == EOF)
  367.       return NULL;
  368.   }
  369. #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
  370.  
  371. #ifdef MOUNTED_GETMNTTBL    /* DolphinOS goes it's own way */
  372.   {
  373.     struct mntent **mnttbl=getmnttbl(),**ent;
  374.     for (ent=mnttbl;*ent;ent++)
  375.       {
  376.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  377.     me->me_devname = xstrdup ( (*ent)->mt_resource);
  378.     me->me_mountdir = xstrdup( (*ent)->mt_directory);
  379.     me->me_type =  xstrdup ((*ent)->mt_fstype);
  380.     me->me_dev = -1;    /* Magic; means not known yet. */
  381.     me->me_next = NULL;
  382.     
  383.     /* Add to the linked list. */
  384.     mtail->me_next = me;
  385.     mtail = me;
  386.       }
  387.     endmnttbl();
  388.   }
  389. #endif
  390.  
  391. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  392.   {
  393.     struct mnttab mnt;
  394.     char *table = MNTTAB;
  395.     FILE *fp;
  396.     int ret;
  397.  
  398.     fp = fopen (table, "r");
  399.     if (fp == NULL)
  400.       return NULL;
  401.  
  402.     while ((ret = getmntent (fp, &mnt)) == 0)
  403.       {
  404.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  405.     me->me_devname = xstrdup (mnt.mnt_special);
  406.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  407.     me->me_type = xstrdup (mnt.mnt_fstype);
  408.     me->me_dev = -1;    /* Magic; means not known yet. */
  409.     me->me_next = NULL;
  410.  
  411.     /* Add to the linked list. */
  412.     mtail->me_next = me;
  413.     mtail = me;
  414.       }
  415.  
  416.     if (ret > 0)
  417.       return NULL;
  418.    if (fclose (fp) == EOF)
  419.       return NULL;
  420.   }
  421. #endif /* MOUNTED_GETMNTENT2.  */
  422.  
  423. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  424.   {
  425.     int bufsize;
  426.     char *entries, *thisent;
  427.     struct vmount *vmp;
  428.  
  429.     /* Ask how many bytes to allocate for the mounted filesystem info.  */
  430.     mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
  431.     entries = xmalloc (bufsize);
  432.  
  433.     /* Get the list of mounted filesystems.  */
  434.     mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
  435.  
  436.     for (thisent = entries; thisent < entries + bufsize;
  437.      thisent += vmp->vmt_length)
  438.       {
  439.     vmp = (struct vmount *) thisent;
  440.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  441.     if (vmp->vmt_flags & MNT_REMOTE)
  442.       {
  443.         char *host, *path;
  444.  
  445.         /* Prepend the remote pathname.  */
  446.         host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
  447.         path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
  448.         me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
  449.         strcpy (me->me_devname, host);
  450.         strcat (me->me_devname, ":");
  451.         strcat (me->me_devname, path);
  452.       }
  453.     else
  454.       {
  455.         me->me_devname = xstrdup (thisent + 
  456.                       vmp->vmt_data[VMT_OBJECT].vmt_off);
  457.       }
  458.     me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
  459.     me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
  460.     me->me_dev = -1;    /* vmt_fsid might be the info we want.  */
  461.     me->me_next = NULL;
  462.  
  463.     /* Add to the linked list. */
  464.     mtail->me_next = me;
  465.     mtail = me;
  466.       }
  467.     free (entries);
  468.   }
  469. #endif /* MOUNTED_VMOUNT. */
  470.  
  471.   /* Free the dummy head. */
  472.   me = mount_list;
  473.   mount_list = mount_list->me_next;
  474.   free (me);
  475.   return mount_list;
  476. }
  477.